#region FileHeader
//////////////////////////////////////////////////////////////////////////////////
// Author:                          Hector Llanos
// Date:                            08.27.2010
// FileName:                        AnimatedTexture.cs
// Reason:                          animate a texture
//////////////////////////////////////////////////////////////////////////////////
#endregion

using System;
using System.Collections.Generic;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Content;
using Microsoft.Xna.Framework.Graphics;
using Microsoft.Xna.Framework.Input;


namespace AnimatedSprite
{
    public class AnimatedTexture
    {
        #region PRIVATE_VARS

        //Maximum direction an image can have
        private int                 m_nMaxFrameDirX;
        private int                 m_nMaxFrameDirY;

        //the actual sprite sheet
        private Texture2D           m_tTexture;
         
        private float               m_fTimePerFrame;

        //which frame we are on
        private int                 m_nFrameX;
        private int                 m_nFrameY;
        
        private float               m_fTotalElapsed;

        //looping info
        private bool                m_bPaused;
        private bool                m_bLoop;

        //how big each frame are
        private int                 m_nFrameWidth;
        private int                 m_nFrameHeight;


        private float               m_fRotation;
        private float               m_fScale;
        private float               m_fDepth;
        private Vector2             m_vOrigin;

        //for changing the color of the animations
        private Color m_pColor;
        #endregion

        #region PROPERTIES

        public Color Color
        {
            get { return m_pColor; }
            set { m_pColor = value; }
        }
        public float Scale
        {
            get { return m_fScale; }
            set { m_fScale = value; }
        }

        public float Depth
        {
            get { return m_fDepth; }
            set { m_fDepth = value; }
        }

        public Vector2 Origin
        {
            get { return m_vOrigin; }
            set { m_vOrigin = value; }
        }

        public int FrameWidth
        {
            get { return m_nFrameWidth; }
            set { m_nFrameWidth = value; }
        }
        public float Rotation
        {
            get { return m_fRotation; }
            set { m_fRotation = value; }
        }
        public int FrameHeight
        {
            get { return m_nFrameHeight; }
            set { m_nFrameHeight = value; }
        }
        public bool IsPaused
        {
            get { return m_bPaused; }
        }
        #endregion

        //contructor
        public AnimatedTexture(Vector2 origin, float rotation,float scale, float depth, bool loop)
        {
            this.Origin = origin;
            this.m_fRotation = rotation;
            this.m_fScale = scale;
            this.m_fDepth = depth;
            this.m_bLoop = loop;
            m_pColor = Color.White;
        }
        //copy contructor 
        public AnimatedTexture(AnimatedTexture texture)
        {
            if (this != texture)
            {
                m_fRotation = texture.m_fRotation;
                Origin = texture.Origin;
                m_fScale = texture.Scale;
                m_fDepth = texture.Depth;
                Color = texture.Color;
                m_nFrameHeight = texture.FrameHeight;
                m_nFrameWidth = texture.FrameWidth;
                m_nMaxFrameDirX = texture.m_nMaxFrameDirX;
                m_nMaxFrameDirY = texture.m_nMaxFrameDirY;
                m_tTexture = texture.m_tTexture;
                m_fTimePerFrame = texture.m_fTimePerFrame;
                m_bLoop = texture.m_bLoop;
                m_bPaused = texture.m_bPaused;
                
            }
        }
        public void Load(ContentManager content, string asset, int maxFramex, int maxFramey, int framesPerSec)
        {
            m_nMaxFrameDirX = maxFramex;
            m_nMaxFrameDirY = maxFramey;

            
            m_tTexture = content.Load<Texture2D>(asset);

            m_fTimePerFrame = 1.0f / (float)framesPerSec;
            m_nFrameX = m_nFrameY = 0;
            m_fTotalElapsed = 0;
            m_bPaused = false;

            FrameWidth = m_tTexture.Width / m_nMaxFrameDirX;
            m_nFrameHeight = m_tTexture.Height / m_nMaxFrameDirY;
        }

        public void UpdateFrame(float elapsed)
        {
            if (m_bPaused)
                return;

            m_fTotalElapsed += elapsed;

            if (m_fTotalElapsed > m_fTimePerFrame)
            {
                m_nFrameX++;
                // Keep the Frame between 0 and the total frames, minus one.
               // Frame = Frame % framecount;
                if (m_nFrameX == m_nMaxFrameDirX)
                {
                    m_nFrameY++;

                    if (m_bLoop || m_nMaxFrameDirY > 1)
                    {
                        m_nFrameX = 0;
                    }
                }

                if (m_nFrameY == m_nMaxFrameDirY)
                {

                    // Start from the beginning if looping
                    if (m_bLoop)
                    {
                        m_nFrameX = m_nFrameY = 0;
                    }
                }

                // Stick to the last frame
                if (!m_bLoop)
                {
                    m_nFrameX = m_nMaxFrameDirX - 1;
                    m_nFrameY = m_nMaxFrameDirY - 1;
                }

                m_fTotalElapsed -= m_fTimePerFrame;
            }
        }

        // best function to render anything to the screen
        public void DrawFrame(SpriteBatch batch, Vector2 screenPos)
        {

          DrawFrame(batch, m_nFrameX, m_nFrameY, screenPos);
        }

        private void DrawFrame(SpriteBatch batch, int frameX, int frameY, Vector2 screenPos)
        {
             Rectangle sourcerect = new Rectangle(FrameWidth * frameX, m_nFrameHeight * frameY, FrameWidth, m_nFrameHeight);
             Rectangle collRect = new Rectangle(1, 1, FrameWidth, m_nFrameHeight);
            
             //actual animation to be drawn
             batch.Draw(m_tTexture, screenPos, sourcerect, m_pColor, m_fRotation, Origin, Scale, SpriteEffects.None, Depth);           
        }

        public void Reset()
        {
            m_nFrameX = m_nFrameY = 0;
            m_fTotalElapsed = 0f;
        }
        public void Stop()
        {
            Pause();
            Reset();
        }
        public void Play()
        {
            m_bPaused = false;
        }
        public void Pause()
        {
            m_bPaused = true;
        }

    }
}
